//
//  RemoteControlClient.m
//  IPTV
//
//  Created by Echo on 14-4-18.
//  Copyright (c) 2014年 Echo. All rights reserved.
//

#import "RemoteControlClient.h"
#import "AppDelegate.h"
#import "IDGenerator.h"
#import "NSDataInfo.h"
#import "Global.h"
#import "NSDataAES.h"

#define Ping_duration 5

@implementation RemoteControlClient
@synthesize netEventHandler;
@synthesize ctrlIP, ctrlPort;

- (id)init {
    self = [super init];
    
    netEventHandler = [[PokerNetEventHandler alloc] init];
    netEventHandler.deletate = self;
    
    ping_time = Ping_duration;
    
    self.ctrlIP = @"www.seavast.com.cn";//for test
    self.ctrlPort = @"18001";//for test 183.13.182.171
    
    return self;
}
-(void)c2sPing {
    [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(c2sPing) object:nil];
    [self performSelector:@selector(c2sPing) withObject:nil afterDelay:ping_time];
}
- (void)dealloc{
    //    [NC removeObserver:self];
}

+(RemoteControlClient*)share {
    static  RemoteControlClient *instance=nil;
    if (instance==nil) {
        instance = [RemoteControlClient new];
    }
    return instance;
}

-(void)openStream {
    
    
//    self.ctrlIP = @"www.seavast.com.cn";//for test
//    self.ctrlIP = @"wyl1990.xicp.net";//for test
    
    self.ctrlPort = @"18001";//for test
    
    NSLog(@"openStream %@: %@", self.ctrlIP, ctrlPort);
    
    [netEventHandler connectToHost:ctrlIP onPort:[ctrlPort intValue]];
}
int calCRC(unsigned char *s, int length) {
    
    if (NULL == s || length <= 0) {
        return -1;
    }
    int crc = 0x00; // initial value
    int polynomial = 0x1021;
    for (int index = 0; index < length; index++) {
        Byte b = s[index];
        //        NSLog(@"s[%d], 0x%02x", index, s[index]);
        for (int i = 0; i < 8; i++) {
            Boolean bit = ((b >> (7 - i) & 1) == 1);
            Boolean c15 = ((crc >> 15 & 1) == 1);
            crc <<= 1;
            if (c15 ^ bit)
                crc ^= polynomial;
        }
    }
    crc &= 0xffff;
    return crc;
}
/*
 协议头（2字节） + 数据长度（2字节，长度的值，高位在前，假如为n） + 控制命令（2字节，高位在前） + 保留（2字节） +  数据（n - 10）+ 校验( 2字节，crc16ccitt) + 结束符(2字节)
 */

/*
 校验部分为：数据长度（包含）到数据部分（包含）
 数据加密部分为：校验部分加上校验码
 校验方式：CRC16-CCITT ,多项式采用 0x1021
 加密方式：AES/CBC/PKCS5Padding
 */

/*
 0x1000手机登录到服务器
 数据为空
 
 0x1002 心跳
 数据部分为:设备ID
 服务器回复数据：
 0x2002回复心跳
 
 */

// 0x1000登陆 0x1003获取在线设备列表 0x1007 开始学习
-(void) startRemoteCmd:(unsigned char)firstBit sec:(unsigned char)SecBit dataStr:(NSString*)datastr{
    //数据长度（2字节，长度的值，高位在前，假如为n） + 控制命令（2字节，高位在前） + 保留（2字节） +  数据（n - 10）+ 校验( 2字节，crc16ccitt)
    //    NSString *content = [NSString stringWithFormat:@"\0\0%c\0\0\0", 0x10];//6位
    //    NSString *contentd = [NSString stringWithFormat:@"%c%c%c", 0x10, 0x43, 0x43];//6位
    //    int asciiCode = 65;
    //    NSString *string = [NSString stringWithFormat:@"%c%c", 16,asciiCode]; // A
    
    unsigned int datalengh = 8+[datastr length];//数据长度;
    unsigned char *plength = (unsigned char *)&datalengh;
    unsigned char testlength[100] = {'\0'};
    memcpy(testlength, plength+1, 1);
    memcpy(testlength+1, plength, 1);
    
    unsigned char test[1024] = {'\0'};
    //    memset(testd, 0, sizeof(testd)/sizeof(char));
    test[0] = testlength[0];//数据长度
    test[1] = testlength[1];//数据长度
    test[2] = 0x10;//控制命令
    test[2] = firstBit;
    test[3] = SecBit;//控制命令
    test[4] = 0x00;//保留
    test[5] = 0x00;//保留
    
    const char *pcontent = NULL;
    if (datastr) {
        pcontent = (const char *) [datastr UTF8String];
    }
    for (int i=0; i<[datastr length]; i++) {
        test[i+6] = pcontent[i];
//        NSLog(@"hello : %c", test[i+5]);
    }
    
    unsigned int crcx = 0;
    crcx = calCRC(test, 6+[datastr length]);//2位校验
    
    unsigned char *p = (unsigned char *)&crcx;
    unsigned char testxxd[100] = {'\0'};
    memcpy(testxxd, p, 1);
    memcpy(testxxd+1, p+1, 1);
    
    //    memcpy(testxxd, &crcx+8, 1);
    //    NSLog(@"crc : 0x %x %d %lu %lu", crcx, crcx, sizeof(&crcx), sizeof(int));
    //    NSLog(@"0xxxx:%x %x", testxxd[0], testxxd[1]);
    //
    //    NSLog(@"0x:%x ", crcx); 0x 198a
    
    NSMutableData *crcdata = [NSMutableData data];
    [crcdata appendBytes:test length:6+[datastr length]];
    [crcdata appendBytes:&testxxd[1] length:1];
    [crcdata appendBytes:&testxxd[0] length:1];
    
    NSLog(@"发送数据");
    
    char* aaaaxxxx = (char*)[crcdata bytes];
    for (int i=0; i<[crcdata length]; i++) {
        NSLog(@"msg[%d]:0x%02x", i, aaaaxxxx[i]);
    }
    
    NSData *encrydata = [crcdata AES256EncryptWithKey];//加密
    //拼接首尾数据
    const char a[1] = {'@'};//十进制编码 64 0x40
    const char c = 35;//十进制编码 35 0x23
    NSMutableData *newSenddata = [NSMutableData data];
    [newSenddata appendBytes:a length:1];
    [newSenddata appendBytes:a length:1];
    [newSenddata appendData:encrydata];
    [newSenddata appendBytes:&c length:1];
    [newSenddata appendBytes:&c length:1];
    
    //    NSLog(@"开始");
    //
    //    char* aaaaxx = (char*)[newSenddata bytes];
    //    for (int i=0; i<[newSenddata length]; i++) {
    //        NSLog(@"msg[%d]:0x%x", i, aaaaxx[i]);
    //    }
    [netEventHandler sendNetData:newSenddata];
}
-(void)stopc2sPing{
    [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(c2sPing) object:nil];
}
-(void)recvStr:(NSString*)str{
    
}
-(void)recvData:(NSData*)recvData{
    NSLog(@"收到服务器数据");
    char* pchar = (char*)[recvData bytes];

    NSData *reveSubData = [NSData dataWithBytes:pchar+2 length:[recvData length]-4];
    NSData *encrydata = [reveSubData AES256DecryptWithKey];
    
    char* pRecv = (char*)[encrydata bytes];
    if (pRecv) {
        printf("recv1: ");
        for (int i=0; i<[encrydata length]; i++) {
            printf("0x%02x ", pRecv[i] );
        }
        printf("\n");
        printf("recv2: ");
        for (int i=0; i<[encrydata length]; i++) {
            printf("%c", pRecv[i] );
//            NSLog(@"recv[%d]:0x%02x %c", i, pRecv[i], pRecv[i]);
        }
        printf("\n");
        if (pRecv[2]==0x20 && pRecv[3]==0x03) {
            NSLog(@"消息发送成功");
            if (!isConnect) {
                [NC postNotificationName:CONNECT_SUC_REMOTE object:nil];
            }
            isConnect = YES;
        }else if (pRecv[2]==0x20 && pRecv[3]==0x04) {
            NSLog(@"消息发送失败");
        }else if (pRecv[2]==0x20 && pRecv[3]==0x05) {
            NSLog(@"回复设备在线列表");
            if ([encrydata length] > 23) {
                NSString *strNetState =  [NSString stringWithFormat:@"%c", pRecv[20]];
                if ([strNetState intValue] == 1) {
                    NSLog(@"设备在线");
                    NSString *string = [NSString string];
                    for (int i=0; i<12; i++) {
                        string = [string stringByAppendingFormat:@"%c", pRecv[i+7]];
                    }
                    NSLog(@"string :%@", string);
                    [NC postNotificationName:REMOTE_DEVICE_NAME object:string];
                }else{
                    NSLog(@"设备离线");
                }
            }
        }else if (pRecv[2]==0x20 && pRecv[3]==0x02) {
            NSLog(@"回复心跳");
        }else if (pRecv[2]==0x30 && pRecv[3]==0x03) {//学习码
            if ([encrydata length] > 8) {
                NSString *string = [NSString string];
                for (int i=0; i<[encrydata length]-8; i++) {
                    string = [string stringByAppendingFormat:@"%c", pRecv[i+6]];
                }//1010 0100 36+128=164
                NSLog(@"string :%@", string);
                [NC postNotificationName:NOTI_TEMP_INFO object:string];
            }
        }
    }
}
#pragma mark
-(BOOL)isNetConnect{
    return isConnect;
}
-(void)disConnect{
    [netEventHandler disconnect];
    isConnect = NO;
}
//连接成功后
-(void)didConnect {
    NSLog(@"remote didConnect");
    if ([self.ctrlPort intValue] == 18001) {
        [self startRemoteCmd:0x10 sec:0x00 dataStr:nil];//登陆
    }else if  ([self.ctrlPort intValue] == import_port) {
        NSString *content = @"<data><cmd>1001</cmd></data>";
        [netEventHandler sendString:content];
    }
}
-(void)streamDidOpen:(DDXMLElement *)root{
    
}
-(void)loginFail:(DDXMLElement*)failElement {//登录失败
    NSString *error = nil;
    if ([failElement childCount]>0) {
        error = [[failElement childAtIndex:0] stringValue];
    }
    if (error == nil) {//不能为nil, 为nil会被认为登录成功。
        error = @"error";
    }
    if ([failElement elementForName:@"not-authorized"]) {
        error = @"not-authorized";
    }
    NSLog(@"登录失败。错误信息：%@", error);
}
-(void)didReadElement:(DDXMLElement*)xmlElement{
    
}
-(void)didDisconnect{
    isConnect = NO;
}
-(void)networkStateChanged{
    isConnect = NO;
}

@end

